package com.start.avue.mapper;

import cn.hutool.core.convert.Convert;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.start.avue.tools.AvueTools;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;

public abstract class AvueBaseDicDataMapper extends StartBaseAvueMapper implements StartAvueAnalysisDicData {
    private final static Logger log = LoggerFactory.getLogger(AvueBaseDicDataMapper.class);
    private static final Pattern URL_START = Pattern.compile("^http[s]{0,1}://", Pattern.CASE_INSENSITIVE);
    private static final Pattern URL_PATH_SEPARATOR = Pattern.compile("/+", Pattern.CASE_INSENSITIVE);

    private AvueDicDataMapper dicData;


    @Override
    public void init(String startHomeUrl, JSONObject column, Map<String, String> headers) {
        super.init(startHomeUrl, column, headers);
        this.loadMapperData();
    }

    public void loadMapperData() {
        JSONArray dicData = null;
        if (column.containsKey("dicData") && !column.getJSONArray("dicData").isEmpty()) {
            dicData = loadLocalDicData();
        }
        if (column.containsKey("dicUrl") && StringUtils.isNotEmpty(column.getString("dicUrl"))) {
            dicData = loadRemoteDicData();
        }
        AvueDicDataMapper mapper = analysisDicData(dicData);
        this.dicData = mapper;
    }

    private JSONArray loadLocalDicData() {
        if (!column.containsKey("dicData")) {
            return null;
        }
        return column.getJSONArray("dicData");
    }

    /**
     * 处理远程字典类型数据
     */
    private JSONArray loadRemoteDicData() {
        String url = analysisUrl(column.getString("dicUrl"));
        String dicMethod = column.containsKey("dicMethod") ? column.getString("dicMethod") : "get";
        JSONObject dicQuery = column.containsKey("dicQuery") ? column.getJSONObject("dicQuery") : new JSONObject();
        HttpRequest httpRequest = createHttpRequest(url, dicMethod, dicQuery);
        log.error("远程数据加载地址：" + column.getString("prop") + "\n" + httpRequest.getUrl());
        HttpResponse execute = httpRequest.execute();
        if (execute.getStatus() != 200) {
            execute.close();
            log.error("请求错误：" + httpRequest.getUrl());
            return null;
        }
        JSONObject result = JSONObject.parseObject(execute.body());
        execute.close();
        if (!result.containsKey("data")) {
            log.warn("远程数据中未找到有效数据：" + execute.body());
            return null;
        }
        return result.getJSONArray("data");

    }

    /**
     * 创建网络请求
     *
     * @param url
     * @param dicMethod
     * @param dicQuery
     * @return
     */
    protected HttpRequest createHttpRequest(String url, String dicMethod, JSONObject dicQuery) {
        HttpRequest httpRequest = null;
        if (dicMethod.equalsIgnoreCase("get")) {
            StringBuilder tempUrlParameter = new StringBuilder();
            if (!dicQuery.isEmpty()) {
                Set<Map.Entry<String, Object>> entries = dicQuery.entrySet();
                for (Map.Entry<String, Object> entrie : entries) {
                    tempUrlParameter.append(entrie.getKey());
                    tempUrlParameter.append("=");
                    tempUrlParameter.append(Convert.toStr(entrie.getValue()));
                }
            }
            if (url.contains("?")) {
                int index = url.indexOf("?");
                String tempUrl = url.substring(0, index);
                tempUrl += "?" + tempUrlParameter.toString();
                tempUrl += "&" + url.substring(index + 1);
                url = tempUrl;
            } else {
                url += "?" + tempUrlParameter;
            }
            httpRequest = HttpRequest.get(url);
        } else {
            httpRequest = HttpRequest.post(url).body(dicQuery.toJSONString());
        }
        if (headers == null || headers.isEmpty()) return httpRequest;
        return httpRequest.addHeaders(headers);
    }

    /**
     * 解析url 地址
     *
     * @param url
     * @return
     */
    protected String analysisUrl(String url) {
        return AvueTools.analysisUrl(startHomeUrl, url);
    }

//    public static void main(String[] args) {
//        AvueCheckBoxMapper avueCheckBoxMapper = new AvueCheckBoxMapper();
//        avueCheckBoxMapper.init("HTTP://corsyn.uicp.net:17288/zentao/", new JSONObject(), new HashMap<>());
//        String analysisUrl = avueCheckBoxMapper.analysisUrl("#{baseUrl}bug-view-180/c");
//        System.out.println(analysisUrl);
//    }

    /**
     * 默认除字典数据或远程数据
     *
     * @param array
     * @return
     */
    public AvueDicDataMapper analysisDicData(JSONArray array) {
        Map<String, String> labelDic = new HashMap<>();
        Map<String, String> valueDic = new HashMap<>();
        if (array == null || array.isEmpty()) return new AvueDicDataMapper(labelDic, valueDic);
        String labelKey = "label";
        String valueKey = "value";
        if (column.containsKey("props")) {
            JSONObject props = column.getJSONObject("props");
            if (props.containsKey("label")) {
                labelKey = props.getString("label");
            }
            if (props.containsKey("value")) {
                valueKey = props.getString("value");
            }
        }

        for (int i = 0; i < array.size(); i++) {
            JSONObject itemData = array.getJSONObject(i);
            String label = itemData.getString(labelKey);
            String value = itemData.getString(valueKey);
            if (!labelDic.containsKey(label)) {
                labelDic.put(label, value);
            }
            if (!valueDic.containsKey(value)) {
                valueDic.put(value, label);
            }
        }
        return new AvueDicDataMapper(labelDic, valueDic);
    }

    @Override
    public Object labelToValue(String label) {
        return dicData.getLabelDicValue(label);
    }

    @Override
    public Object valueToLabel(Object value) {
        if (value == null) {
            return null;
        }
        String valStr = String.valueOf(value);
        return dicData.getValueDicValue(valStr);
    }
}
